/*
 * Diego da Rocha Borges
 * Otávio Zabaleta
 */

#ifndef SYMBOL_TABLE_H
#define	SYMBOL_TABLE_H

// This value must be a PRIME one!!
#define TABLE_SIZE 911

#define SYMBOL_UNDEFINED 0
#define SYMBOL_LIT_INTEGER 1
#define SYMBOL_LIT_TRUE 3
#define SYMBOL_LIT_FALSE 4
#define SYMBOL_LIT_CHAR 5
#define SYMBOL_LIT_STRING 6
#define SYMBOL_IDENTIFIER 7

/*
 * Table entry structure. Holds the information about an entry.
 * TODO Does the token information is needed here??
 */
typedef struct {
   char* lexeme;
   int type;

} table_entry;

/*
 * Implements a linked list to hold the symbol table entries
 */
typedef struct {
   table_entry* data;
   struct table_entry_node* next;
} table_entry_node;

/*
 * Symbol Table type definition.
 * <p>
 * A Symbol Table is basiclly a vector of pointers to table_entry_node elements.
 * Each table_entry_node holds the data information about a token/lexeme.
 * </p>
 */
typedef struct {
    table_entry_node* entries[TABLE_SIZE];
} symbol_table;

/**
 * Initializes the symbol table.
 * <p>
 * For each entry on table, this entry is setted to NULL.
 * </p>
 *
 * @param table a pointer to the table that need to be initialized.
 */
void init_symbol_table(symbol_table* table);

/**
 * Calculates the hash address for a character sequence.
 *
 * @param text lexeme used to generate a hash address releted to the symbol table.
 * @return the address for the lexeme in the symbol table.
 */
int hash_address(char *lexeme);

/**
 * Inserts a new entry to a symbol table.
 * <p>
 * If the lexeme already exists in the symbol table, a reference to the table entry
 * is returned, otherwise, a new entry is created and a reference to this new entry is
 * returned.
 * </p>
 *
 * @param table a pointer to the symbol table which will receive the new entry.
 * @param lexeme the lexeme to be inserted in the table of symbols.
 * @param type the type of the token (if it is a literal or an identifier for example)
 * @return a pointer to the entry in the symbol table for the inserted lexeme.
 */
table_entry_node* insert_entry(symbol_table* table, char* lexeme, int type);

/**
 * Look up a symbol table entry by it's lexeme information.
 * 
 * @param table a ready only copy of the table to look up the entry.
 * @param lexeme the lexeme to be looked up in the symbol table.
 * @param type the lexeme type (identifier, literal...)
 * @return a pointer to the entry of the symbol table.
 */
table_entry_node* lookup(symbol_table table, char* lexeme, int type);

/**
 * Prints the symbol table in the shell.
 * 
 * @param table a ready only copy of the table.
 * @return the entries count of the table.
 */
void print_symbol_table(symbol_table table);

/**
 * Creates a new table_entry_node using a lexeme and it's token as information for
 * the table_entry data of the node.
 *
 * @param lexeme a lexeme
 * @param type the type of the token (if it is a literal or an identifier for example)
 * @return a new entry node in the symbol table.
 */
table_entry_node* create_entry_node(char* lexeme, int type);

#endif	/* SYMBOL_TABLE_H */

